装饰器
概述
装饰器(Decorator)是Python中一种非常强大的功能,它允许我们在不修改函数或方法代码的情况下,动态地为其添加功能。装饰器本质上是一个函数,它接收另一个函数作为参数,并返回一个新的函数。装饰器在Python中广泛应用于日志记录、权限检查、缓存、事务处理等场景。
理论解释
函数作为一等公民
在Python中,函数是一等公民(First-Class Citizen),这意味着函数可以像其他对象一样被传递、赋值给变量、作为参数传递给其他函数,以及从函数中返回。这种特性为装饰器的实现提供了基础。
装饰器的基本结构
一个装饰器通常由两部分组成:
- 装饰器函数:这是一个高阶函数,它接收一个函数作为参数,并返回一个新的函数。
- 被装饰的函数:这是我们希望添加额外功能的原始函数。
装饰器的基本结构如下:
def decorator_function(original_function):
def wrapper_function(*args, **kwargs):
# 在调用原始函数之前执行的代码
result = original_function(*args, **kwargs)
# 在调用原始函数之后执行的代码
return result
return wrapper_function
使用装饰器
在Python中,我们可以使用@符号来应用装饰器。例如:
@decorator_function
def my_function():
pass
这等价于:
def my_function():
pass
my_function = decorator_function(my_function)
代码示例
示例1:简单的日志装饰器
假设我们希望在每次调用某个函数时,记录一条日志信息。我们可以使用装饰器来实现这一功能。
def log_decorator(func):
def wrapper(*args, **kwargs):
print(f"Calling function {func.__name__} with args: {args}, kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f"Function {func.__name__} returned: {result}")
return result
return wrapper
@log_decorator
def add(a, b):
return a + b
# 调用被装饰的函数
add(3, 5)
输出:
Calling function add with args: (3, 5), kwargs: {}
Function add returned: 8
示例2:带参数的装饰器
有时,我们希望装饰器能够接收参数。这可以通过创建一个装饰器工厂函数来实现。
def repeat(num_times):
def decorator_repeat(func):
def wrapper_repeat(*args, **kwargs):
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper_repeat
return decorator_repeat
@repeat(num_times=3)
def greet(name):
print(f"Hello, {name}!")
# 调用被装饰的函数
greet("Alice")
输出:
Hello, Alice!
Hello, Alice!
Hello, Alice!
实践练习
练习1:计时装饰器
编写一个装饰器,用于计算函数执行的时间。
import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} took {end_time - start_time} seconds to execute.")
return result
return wrapper
@timer_decorator
def slow_function():
time.sleep(2)
print("Function executed.")
# 调用被装饰的函数
slow_function()
练习2:权限检查装饰器
编写一个装饰器,用于检查用户是否有权限执行某个函数。如果用户没有权限,则抛出一个异常。
def permission_required(permission):
def decorator_permission(func):
def wrapper_permission(*args, **kwargs):
if not has_permission(permission):
raise PermissionError("You do not have the required permission.")
return func(*args, **kwargs)
return wrapper_permission
return decorator_permission
def has_permission(permission):
# 模拟权限检查逻辑
return permission == "admin"
@permission_required("admin")
def delete_user(user_id):
print(f"User {user_id} deleted.")
# 调用被装饰的函数
try:
delete_user(123)
except PermissionError as e:
print(e)
总结
装饰器是Python中一个非常强大的工具,它允许我们在不修改原始函数代码的情况下,为其添加额外的功能。通过掌握装饰器的使用,你可以编写出更加灵活和可维护的代码。希望本教程能够帮助你理解装饰器的基本概念和使用方法,并通过实践练习加深你的理解。